<?php

require_once "Basic.php";

/*

Este é um formulário que deve ser "preenchido" em duas partes.

Faz uso de sessão para guardar valores entre uma parte e outra.

Índices no array $_SESSION:

  - FILIAL_OBTENCAO
  - FILIAL_DEVOLUCAO
  - DATA_PREV_INICIO
  - DATA_PREV_FIM
  - ESTAGIO_RESERVA (1, 2, 3, 4, 5)
    1 => O sujeito ainda não preencheu nada.
    2 => Preenchendo data/filial.
    3 => Preencheu data/filial.
    4 => Preenchendo modelo.
    5 => Preencheu modelo.

*/

class MakeReservation extends BasicEntity {
  
  private $stage;
  private $action;
  private $idReserva;
  
  public function __construct() {
    if(!isset($_SESSION[ESTAGIO_RESERVA])) {
      $_SESSION[ESTAGIO_RESERVA] = PREENCHEU_NADA;
    }
    
    switch($_SESSION[ESTAGIO_RESERVA]) {
      case PREENCHEU_NADA:
      case PREENCHENDO_DATAFILIAL:
        $this->action = "PreencherDataFilial";
        $filialAll = Filial::getAllForChoice();
        $this->fields = array (
          new FormField(true, "initialDate", htmlentities("Data/Hora Prevista para Início"),
                        new FormFieldDateHourMinute(true)),
          new FormField(true, "endDate", htmlentities("Data/Hora Prevista para Fim"),
                        new FormFieldDateHourMinute(true)),
          new FormField(true, "initialFilial", htmlentities("Filial de Obtenção do Veículo"),
                        new FormFieldChoice($filialAll)),
          new FormField(true, "finalFilial", htmlentities("Filial de Devolução do Veículo"),
                        new FormFieldChoice($filialAll)),
        );
        break;
      case PREENCHEU_DATAFILIAL:
      case PREENCHENDO_MODELO:
        $this->action = "PreencherModelo";
        $dateTimeBegin = FormFieldDateHourMinute::toDateTime($_SESSION["DATA_PREV_INICIO"]);
        $dateTimeEnd = FormFieldDateHourMinute::toDateTime($_SESSION["DATA_PREV_FIM"]);
        $allModels = Modelo::getAllForChoice($_SESSION["FILIAL_OBTENCAO"], $dateTimeBegin, $dateTimeEnd);
        if(count($allModels) > 0) {
          $this->fields = array (
            new FormField(true, "model", htmlentities("Escolha o modelo desejado"), new FormFieldChoice($allModels))
          );
        }
        else {
          $this->fields = array();
        }
        break;
      case PREENCHEU_MODELO:
        clearReservationSession();
        break;
    }
    $this->processFields();
  }
  
  protected function actionDescription() {
    return $this->action;
  }
  
  public function actionPreencherDataFilial() {
    $_SESSION[ESTAGIO_RESERVA] = PREENCHENDO_DATAFILIAL;
    
    foreach($this->fields as $k => $v) {
      $$k = $v->value();
    }
    
    $diff = FormFieldDateHourMinute::toDateTime($endDate)->diff(FormFieldDateHourMinute::toDateTime($initialDate));
    
    if($diff->invert === 0) {
      return htmlentities("A data prevista para entrega deve vir depois da data prevista para aquisição");
    }
    
    $filialAll = Filial::getAllForChoice();
    
    $_SESSION[FILIAL_OBTENCAO] = intval($initialFilial);
    $_SESSION[FILIAL_DEVOLUCAO] = intval($finalFilial);
    $_SESSION[FILIAL_OBTENCAO_NOME] = $filialAll[$initialFilial];
    $_SESSION[FILIAL_DEVOLUCAO_NOME] = $filialAll[$finalFilial];
    $_SESSION[DATA_PREV_INICIO] = $initialDate;
    $_SESSION[DATA_PREV_FIM] = $endDate;
    $_SESSION[ESTAGIO_RESERVA] = PREENCHEU_DATAFILIAL;
    
    return true;
  }
  
  public function actionPreencherModelo() {
    $_SESSION[ESTAGIO_RESERVA] = PREENCHENDO_MODELO;
    
    $filialGet = $_SESSION[FILIAL_OBTENCAO];
    $filialReturn = $_SESSION[FILIAL_DEVOLUCAO];
    $dateBegin = FormFieldDateHourMinute::toDateTime($_SESSION[DATA_PREV_INICIO]);
    $dateEnd = FormFieldDateHourMinute::toDateTime($_SESSION[DATA_PREV_FIM]);
    $model = intval($this->fields["model"]->value());
    
    if(!array_key_exists($model, Modelo::getAll($filialGet, $dateBegin, $dateEnd))) {
      return htmlentities("O modelo selecionado já não está disponível mais. Isso pode ter acontecido pois alguém " .
                          "reservou o último disponível.");
    }
    
    $db = new DBUtils();
    
    try {
      $db->connect();
      
      $insertQuery = <<<IQ
insert into Reserva (previsaoInicio, previsaoTermino, modelo, cliente, filialObtencao, filialDevolucao)
values (?, ?, ?, ?, ?, ?)
IQ;
      $insertArgs = array($dateBegin, $dateEnd, $model, $_SESSION[SESSION_LOGIN], $filialGet, $filialReturn);
      $db->runQuery($insertQuery, $insertArgs);
      
      $db->runQuery("select ident_current('Reserva') as idReserva");
      $this->idReserva =  $db->getItem()->idReserva;
      
      $db->close();
    }
    catch(DBError $e) {
      $db->close(false);
      logMessage($e->errors, "MakeReservation");
      return "Falha no banco de dados. O erro foi reportado.";
    }
    
    $_SESSION[ESTAGIO_RESERVA] = PREENCHEU_MODELO;
    
    return true;
  }
  
  public function actionError() {
    return "Session mal configurada.";
  }
  
  public function valid() {
    return $this->stage !== MakeReservation::STAGE_FAIL;
  }
  
  public function getStage() {
    return $this->stage;
  }
  
  public function hasModels() {
    return count($this->fields) > 0;
  }
  
  public function getIdReserva() {
    return $this->idReserva;
  }
}

mustBeClient();
correctStdFormGET();

$page = new Page("Fazer uma reserva");

if(!isset($_SESSION[ESTAGIO_RESERVA])) {
  $_SESSION[ESTAGIO_RESERVA] = PREENCHEU_NADA;
}

if($_SESSION[ESTAGIO_RESERVA] == PREENCHEU_NADA || $_SESSION[ESTAGIO_RESERVA] == PREENCHENDO_DATAFILIAL) {
  $makeReservation = new MakeReservation();
  $form = new StdForm($makeReservation, $_GET, $_POST, "", "", "MakeReservation.php");
  $form->processForm();
}

if($_SESSION[ESTAGIO_RESERVA] == PREENCHEU_DATAFILIAL) {
  $_GET[StdForm::ACTION_KEY] = StdForm::ACTION_VALUE_PRINT;
  $_SESSION[ESTAGIO_RESERVA] = PREENCHENDO_MODELO;
}

if($_SESSION[ESTAGIO_RESERVA] == PREENCHENDO_MODELO) {
  $makeReservation = new MakeReservation();
  if($makeReservation->hasModels()) {
    $form = new StdForm($makeReservation, $_GET, $_POST, "",
                        "<p><strong>Reserva realizada com sucesso.</strong></p>", "MakeReservation.php");
    if($form->processForm() && $form->receiving()) {
      $ok = true;
    }
  }
  else {
    $page->addContent("<p>" . htmlentities("Não há veículos livres para as data/horário/filial selecionadas.") . "</p>"); 
    $clear = true;
  }
}

if($_SESSION[ESTAGIO_RESERVA] == PREENCHEU_MODELO || (isset($clear) && $clear === true)) {
  clearReservationSession();
}

if(!isset($ok) || $ok !== true) {
  $page->addContent("<p><a href='CancelMakeReservation.php'>Cancelar Esta Requisição de Reserva</a></p>");
}
else {
  $page->addContent("<p><strong>Código da Reserva:</strong> ". $makeReservation->getIdReserva() . "</p>");
}

if(isset($form)) {
  $page->addContent($form->getHtml());
}

switch($_SESSION[ESTAGIO_RESERVA]) {
case PREENCHEU_DATAFILIAL:
case PREENCHENDO_MODELO:
case PREENCHEU_MODELO:
  $rep = new Report();
  $repItem = new ReportItem("-");
  $repItem->addLine("Data Prevista de Início", $_SESSION[DATA_PREV_INICIO]);
  $repItem->addLine("Data Prevista de Fim", $_SESSION[DATA_PREV_FIM]);
  $repItem->addLine("Filial de Obtenção", $_SESSION[FILIAL_OBTENCAO_NOME]);
  $repItem->addLine("Filial de Devolução", $_SESSION[FILIAL_DEVOLUCAO_NOME]);
  $rep->addItem($repItem);
  $page->addContent($rep->getHtml());
  break;
}

echo $page->getHtml();
